#include <stdio.h>
#include <stdlib.h>
#include "MPX_SUPT.h"

#define SIZE 20
#define READY 1000
#define WAIT 2000
#define BLOCK 3000
#define SUSREADY 4000
#define SUSBLOCK 5000


struct listNode
{
	char *data;
	struct listNode *nextPtr;
};

typedef struct listNode ListNode;
typedef ListNode *ListNodePtr;

struct list{
	ListNodePtr head;
};

typedef struct list List;
typedef List *ListPtr;
typedef struct list Ready;
typedef Ready *ReadyPtr;
typedef struct list Wait;
typedef Wait *WaitPtr;
typedef struct list Block;
typedef Block *BlockPtr;
typedef struct list SusReady;
typedef SusReady *SusReadyPtr;
typedef struct list SusBlock;
typedef SusBlock *SusBlockPtr;



void insertPCB(ListPtr sPtr, char *value);
char removePCB(ListPtr sPtr, char *value);
int isEmpty(ListPtr sPtr);
void printPCB(ListPtr currPtr);
char findPCB(ListPtr sPtr, char *value);
void instructions(void);

int main(void)
{
	ListPtr startPtr;
	int choice;
	char item[80];


	startPtr = sys_alloc_mem(sizeof(List));
	startPtr->head=NULL;

	instructions();
	printf("?");
	scanf("%d", &choice);

	while(choice !=4)
	{
		switch(choice)
		{
			case 1:

			printf("Enter a character string: \n");
			scanf("%s", item);

			insertPCB(startPtr, item);
			printPCB(startPtr);

			break;

			case 2:
			if(!isEmpty(startPtr))
			{
				printf("Enter character to be deleted: ");
				scanf("%s", &item);

				if(removePCB(startPtr, item))
				{
					printf("%s deleted.\n", item);
					printPCB(startPtr);
				}
				else
					printf("%s not found.\n", item);
			}
			else
			 	printf("List is empty.\n");

			break;

			case 3:
			if(!isEmpty(startPtr))
			{
				printf("Enter character to be found: ");
				scanf("%s", &item);

				if(findPCB(startPtr, item))
				{
					printf("%s deleted.\n", item);
					printPCB(startPtr);
				}
				else
					printf("%s not found.\n", item);
			}
			else
			 	printf("List is empty.\n");

			break;

			default:
			printf("Invalid choice.\n");
			instructions();
		}

		printf("?");
		scanf("%d", &choice);
	}

	printf("End.\n");
	return 0;

}

void instructions(void)
{
	printf("Enter your choice:\n"
	    "   1 to insert an element into the list.\n"
	    "   2 to delete an element from the list.\n"
	    "   3 to find an element from the list.\n"
	    "   4 to end.\n");
}

void insertPCB(ListPtr sPtr, char *value)
{
	ListNodePtr newPtr;
	ListNodePtr prevPtr;
	ListNodePtr currPtr;

	newPtr = sys_alloc_mem(sizeof(ListNode));
	newPtr->nextPtr=NULL;
	newPtr->data = sys_alloc_mem(strlen(value)+1 * sizeof(char));

	strcpy(newPtr->data, value);


	if(newPtr !=NULL){

		prevPtr = NULL;
		currPtr = sPtr->head;

		if (currPtr == NULL) {
			sPtr->head = newPtr;
			return;
		}
		while(currPtr != NULL && strcmp(value, currPtr -> data) > 0 )
		{
			prevPtr = currPtr;
			currPtr = currPtr ->nextPtr;
		}

		if(prevPtr == NULL)
		{
			newPtr -> nextPtr = sPtr->head;
			sPtr->head = newPtr;
		}
		else if( prevPtr != NULL && currPtr != NULL)
		{
			prevPtr -> nextPtr = newPtr;
			newPtr -> nextPtr = currPtr;
		}
		else if(prevPtr != NULL && currPtr == NULL)
		{
		   prevPtr->nextPtr = newPtr;
		}
	}
	else
	{
		printf("not inserted. No memory avaliable.\n");
	}
}

char removePCB(ListPtr sPtr, char *value)
{
	ListNodePtr tempPtr=NULL;
	ListNodePtr prevPtr=NULL;
	ListNodePtr currPtr;

	if(strcmp(value, sPtr -> head ->data) == 0)
	{

		tempPtr =sPtr->head;
		sPtr->head = sPtr->head->nextPtr;
		free(tempPtr->data);
		free(tempPtr);
		return 1;
	}
	else
	{
		prevPtr = sPtr->head;
		currPtr = prevPtr->nextPtr;

		while(currPtr != NULL && strcmp(currPtr -> data, value) !=0)
		{
			prevPtr = currPtr;
			currPtr = currPtr ->nextPtr;
		}

		if(currPtr != NULL)
		{
			tempPtr = currPtr;
			prevPtr -> nextPtr = currPtr -> nextPtr;
			free(tempPtr->data);
			free(tempPtr);
			return 1;
		}
	}
	return 0;
}

char findPCB(ListPtr sPtr, char *value)
{
	ListNodePtr tempPtr=NULL;
	ListNodePtr prevPtr=NULL;
	ListNodePtr currPtr;

	if(strcmp(value, sPtr -> head ->data) == 0)
	{

		tempPtr =sPtr->head;
		sPtr->head = sPtr->head->nextPtr;
		free(tempPtr->data);
		free(tempPtr);
		return 1;
	}
	else
	{
		printf("Process not found.\n");
	}
}


int isEmpty(ListPtr sPtr)
{
	return (sPtr->head == NULL);
}

void printPCB(ListPtr currPtr)
{
	ListNodePtr next;

	if(currPtr->head == NULL)
	{
		printf("List is empty.\n");
	}
	else
	{
		printf("The list is: \n");
		next = currPtr->head;
		while(next != NULL)
		{
			printf("%s  ", next -> data);
			next = next->nextPtr;
		}
		printf("NULL\n");
	}
}